package cn.wolfcode.business.service.impl;

import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.List;

import cn.wolfcode.common.exception.ServiceException;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.wolfcode.business.mapper.BpmnInfoMapper;
import cn.wolfcode.business.domain.BpmnInfo;
import cn.wolfcode.business.service.IBpmnInfoService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

/**
 * 流程定义明细Service业务层处理
 * 
 * @author dafei
 * @date 2024-03-05
 */
@Service
@Transactional
public class BpmnInfoServiceImpl implements IBpmnInfoService 
{
    @Autowired
    private BpmnInfoMapper bpmnInfoMapper;

    @Autowired
    private RepositoryService    repositoryService;

    /**
     * 查询流程定义明细
     * 
     * @param id 流程定义明细主键
     * @return 流程定义明细
     */
    @Override
    public BpmnInfo selectBpmnInfoById(Long id)
    {
        return bpmnInfoMapper.selectBpmnInfoById(id);
    }

    /**
     * 查询流程定义明细列表
     * 
     * @param bpmnInfo 流程定义明细
     * @return 流程定义明细
     */
    @Override
    public List<BpmnInfo> selectBpmnInfoList(BpmnInfo bpmnInfo)
    {
        return bpmnInfoMapper.selectBpmnInfoList(bpmnInfo);
    }

    /**
     * 新增流程定义明细
     * 
     * @param bpmnInfo 流程定义明细
     * @return 结果
     */
    @Override
    public int insertBpmnInfo(BpmnInfo bpmnInfo)
    {
        return bpmnInfoMapper.insertBpmnInfo(bpmnInfo);
    }

    /**
     * 修改流程定义明细
     * 
     * @param bpmnInfo 流程定义明细
     * @return 结果
     */
    @Override
    public int updateBpmnInfo(BpmnInfo bpmnInfo)
    {
        return bpmnInfoMapper.updateBpmnInfo(bpmnInfo);
    }

    /**
     * 批量删除流程定义明细
     * 
     * @param ids 需要删除的流程定义明细主键
     * @return 结果
     */
    @Override
    public int deleteBpmnInfoByIds(Long[] ids)
    {
        return bpmnInfoMapper.deleteBpmnInfoByIds(ids);
    }

    /**
     * 删除流程定义明细信息
     * 
     * @param id 流程定义明细主键
     * @return 结果
     */
    @Override
    public int deleteBpmnInfoById(Long id)
    {
        return bpmnInfoMapper.deleteBpmnInfoById(id);
    }

    @Override
    public void deploy(MultipartFile file, String bpmnLabel, Integer bpmnType, String info) throws IOException {

        if(file == null || file.getSize() <= 0){
            throw new ServiceException("文件异常，操作失败");
        }
        //获取上传文件的后缀名
        String ext = FilenameUtils.getExtension(file.getOriginalFilename());

        if(!"bpmn".equalsIgnoreCase(ext)){
            throw new ServiceException("文件格式不正确，必须是流程文件(bpmn)");
        }

        //流程部署
        Deployment deployment = repositoryService.createDeployment()
                .addInputStream(bpmnLabel, file.getInputStream())
                .deploy();

        //流程定义
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deployment.getId())
                .singleResult();

        //流程定义表保存
        BpmnInfo bpmnInfo = new BpmnInfo();

        bpmnInfo.setBpmnLabel(bpmnLabel);
        bpmnInfo.setInfo(info);
        bpmnInfo.setBpmnType(bpmnType);

        bpmnInfo.setDeployTime(deployment.getDeploymentTime());
        bpmnInfo.setVersion(processDefinition.getVersion());
        bpmnInfo.setProcessDefinitionKey(processDefinition.getKey());

        bpmnInfoMapper.insertBpmnInfo(bpmnInfo);

    }

    @Override
    public InputStream getFlowResource(Long id, String type) {
        BpmnInfo bpmnInfo = bpmnInfoMapper.selectBpmnInfoById(id);

        if(bpmnInfo == null){
            throw new ServiceException("参数异常");
        }
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey(bpmnInfo.getProcessDefinitionKey())
                .processDefinitionVersion(bpmnInfo.getVersion())
                .singleResult();

        InputStream inputStream = null;

        if("xml".equalsIgnoreCase(type)){
            inputStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getResourceName());
        }else if("png".equalsIgnoreCase(type)){

            DefaultProcessDiagramGenerator processDiagramGenerator = new DefaultProcessDiagramGenerator();
            BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
            /**
             * 第一个参数: 流程定义模型
             * 第二个参数: 高亮节点集合
             * 第三个参数: 高亮连线集合
             */
            inputStream = processDiagramGenerator.generateDiagram(bpmnModel,
                    Collections.emptyList(),   //高亮显示当前流程到哪个节点
                    Collections.emptyList(),   //高亮显示流程线
                    "宋体",
                    "宋体",
                    "宋体");

        }
        return inputStream;
    }

    @Override
    public void cancel(Long id) {


        //条件
        BpmnInfo bpmnInfo = bpmnInfoMapper.selectBpmnInfoById(id);
        if(bpmnInfo == null){
            throw new ServiceException("参数异常");
        }
        //数据改动
        //1： bpmnInfo 删除
        bpmnInfoMapper.deleteBpmnInfoById(id);
        //2： 部署相关对象/数据-删除
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey(bpmnInfo.getProcessDefinitionKey())
                .processDefinitionVersion(bpmnInfo.getVersion()).singleResult();
        //3： 如果流程启动流程实例相关-删除--true:级联删除
        repositoryService.deleteDeployment(processDefinition.getDeploymentId(), true);
        //4： 在审核流程中数据状态要恢复--@TODO
        // 套餐审核服务相关数据转改要改动
    }
}
